/******************************************************************************
 * Copyright 2022 The Airos Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include <string>
#include <mutex>
#include <fstream>
#include <sstream>

#include <google/protobuf/text_format.h>
#include <glog/logging.h>

#include "framework/flags.h"
#include "config/config.h"

namespace air {
namespace config {

std::shared_ptr<Config> Config::GetInstance() {
  static std::shared_ptr<Config> s_instance_;
  static std::once_flag s_init_;
  std::call_once(
      s_init_,
      []() { s_instance_.reset(new (std::nothrow) Config()); });
  return s_instance_;
}

void Config::UseDefault() {
  // set default conf params
  {
    auto data_flows = conf_.add_data_flow();
    data_flows->set_name("worker.FakeObuReceiver.FakeObuReceiver");
    data_flows->add_dst("actor.SceneService.SceneService");
  }
  {
    auto data_flows = conf_.add_data_flow();
    data_flows->set_name("actor.VehicleBasicInfoApi.VehicleBasicInfoApi");
    data_flows->add_dst("worker.NetServiceSender.NetServiceSender");
  }
}

Config::Config() {
  const std::string conf_file_path =
    air::link::FLAGS_air_link_conf_dir + "air_link.dataflow";
  std::ifstream conf_file(conf_file_path);
  std::stringstream conf_ss;
  conf_ss << conf_file.rdbuf();
  auto conf_str = conf_ss.str();
  if (conf_str.empty()) {
    UseDefault();
    return;
  }
  if (::google::protobuf::TextFormat::ParseFromString(conf_str, &conf_)) {
    LOG(INFO) << "load data flow conf from " << conf_file_path;
    LOG(INFO) << conf_.DebugString();
    return;
  }
  UseDefault();
}

const air::link::Config Config::Get() const {
  return conf_;
}

std::vector<std::string> Config::GetSendList(const std::string& name) {
  std::vector<std::string> send_list;
  const auto& params = conf_;
  for (int i = 0; i < params.data_flow_size(); ++i) {
    if (params.data_flow(i).name() == name) {
      for (int j = 0; j < params.data_flow(i).dst_size(); ++j) {
        send_list.emplace_back(params.data_flow(i).dst(j));
      }
      break;
    }
  }
  return send_list;
}

}  // namespace config
}  // namespace air
